<?php

namespace app\admin\service\common;


use Faker\Generator as FakerGenerator;
use app\admin\service\admin\DictService;
use app\admin\service\common\SqlProcessService;
use think\facade\Db;

class SmartMockGenerator
{
    protected $faker;
    private static $dictCache = [];

    public function __construct(
        FakerGenerator              $faker,
        protected DictService       $dictService,
        protected SqlProcessService $sqlProcessService
    )
    {
        $this->faker = $faker;
    }

    /**
     * 根据字段元数据智能生成模拟值
     * @param array $definition ra_dev_field 表的一行记录
     * @param array $config 解码后的 config 字段
     * @return mixed
     */
    public function getValue(array $definition)
    {
        $config = $definition['config'];
        $fieldName = $definition['field'];
        $componentType = $config['type'] ?? 'input';
        $optionsType = $config['item_options_type'] ?? '';
        $options = $config['item_options'] ?? null;

        // 优先级 1: 处理带选项的组件 (select, radio, checkbox, tree_select 等)
        if (in_array($componentType, ['select', 'radio', 'checkbox', 'tree_select', 'switch']) && $options) {
            $optionValues = $this->getOptions($optionsType, $options);
            if (!empty($optionValues)) {
                // 对于多选组件，可以随机选择几个值
                if (($config['item_multiple'] ?? 'single') === 'multiple') {
                    $numToSelect = $this->faker->numberBetween(1, min(3, count($optionValues)));
                    return json_encode($this->faker->randomElements($optionValues, $numToSelect));
                }
                return $this->faker->randomElement($optionValues);
            }
        }

        if($componentType === 'ssq_select') {
            return null;
        }

        // 优先级 2: 根据组件类型 (config['type']) 和字段名进行精确匹配
        switch ($componentType) {
            case 'image_upload':
                // 如果是多图，返回JSON字符串
                if (($config['item_multiple'] ?? 'single') === 'multiple') {
                    return json_encode([$this->faker->imageUrl(), $this->faker->imageUrl()]);
                }
                return $this->faker->imageUrl();
            case 'file_upload':
                return 'https://example.com/uploads/file.zip';
            case 'datetime':
                $format = $config['item_date_format'] ?? 'Y-m-d H:i:s';
                return $this->faker->dateTimeThisDecade()->format(str_replace(['YYYY', 'MM', 'DD'], ['Y', 'm', 'd'], $format));
            case 'location_select': // 地图位置选择
                return json_encode([
                    'lng' => $this->faker->longitude,
                    'lat' => $this->faker->latitude,
                    'address' => $this->faker->address
                ]);
            case 'password':
                return '123456';
            case 'rich_text_editor':
                return '<p>' . $this->faker->realText(400) . '</p>';
            case 'order_sn':
                return 'SN' . date('YmdHis') . $this->faker->randomNumber(6);
            case 'random':
                return $this->faker->bothify(str_repeat('?', $config['item_random_length'] ?? 8));
            case 'client_ip':
                return $this->faker->ipv4;
        }

        // 优先级 3: 根据字段名 (`field`) 进行通用匹配
        switch (true) {
            case $fieldName === 'username':
                return $this->faker->unique()->userName;
            case $fieldName === 'email':
                return $this->faker->unique()->safeEmail;
            case $fieldName === 'mobile' || $fieldName === 'phone':
                return $this->faker->phoneNumber;
            case $fieldName === 'realname' || $fieldName === 'name':
                return $this->faker->name;
            case $fieldName === 'nickname':
                return $this->faker->name; // 也可以用其他方式
            case str_contains($fieldName, 'avatar') || str_contains($fieldName, 'cover'):
                return $this->faker->imageUrl();
            case str_contains($fieldName, 'url') || str_contains($fieldName, 'link'):
                return $this->faker->url;
            case str_contains($fieldName, 'address'):
                return $this->faker->address;
            case str_contains($fieldName, 'city'):
                return $this->faker->city;
            case str_contains($fieldName, 'province'):
                return $this->faker->state;
            case str_contains($fieldName, 'title'):
                return $this->faker->sentence(8);
            case str_contains($fieldName, 'content') || str_contains($fieldName, 'summary') || str_contains($fieldName, 'profile') || str_contains($fieldName, 'remark'):
                return $this->faker->realText(150);
            case $fieldName === 'age':
                return $this->faker->numberBetween(18, 60);
            case $fieldName === 'ip':
                return $this->faker->ipv4;
            case str_contains($fieldName, 'uuid'):
                return $this->faker->uuid;
            case str_ends_with($fieldName, '_id'):
                return $this->faker->numberBetween(1, 50); // 模拟外键
        }

        // 优先级 4: 根据数据库类型 (`field_type`) 进行保底生成
        $dbType = $config['field_type'] ?? 'varchar';
        if (str_starts_with($dbType, 'int') || str_starts_with($dbType, 'tinyint')) {
            return $this->faker->numberBetween(0, 100);
        }
        if (str_starts_with($dbType, 'decimal') || str_starts_with($dbType, 'float')) {
            return $this->faker->randomFloat(2, 100, 10000);
        }
        if (str_starts_with($dbType, 'datetime') || str_starts_with($dbType, 'timestamp')) {
            return $this->faker->dateTimeThisYear()->format('Y-m-d H:i:s');
        }
        if (str_starts_with($dbType, 'date')) {
            return $this->faker->date();
        }
        if ($dbType === 'json') {
            return json_encode(['key' => $this->faker->word, 'value' => $this->faker->sentence]);
        }
        if (str_starts_with($dbType, 'varchar')) {
            return $this->faker->word;
        }
        if (str_starts_with($dbType, 'text')) {
            return $this->faker->realText(200);
        }

        return null; // 最终无法匹配则返回 null
    }

    /**
     * 解析各种类型的选项数据
     * @param string $type 'dict', 'sql', 'key_value'
     * @param mixed $options
     * @return array
     */
    private function getOptions(string $type, $options): array
    {
        $cacheKey = $type . '_' . (is_array($options) ? md5(json_encode($options)) : $options);
        if (isset(self::$dictCache[$cacheKey])) {
            return self::$dictCache[$cacheKey];
        }

        $values = [];
        try {
            if ($type === 'dict' && is_string($options)) {
                $result = $this->getDictValues($options);
                $values = array_column($result, 'value');
            } elseif ($type === 'sql' && is_string($options)) {
                $result = $this->sqlProcessService->parseSqlToDict($options);
                $values = array_column($result, 'value');
            } elseif ($type === 'key_value' && is_array($options)) {
                $values = array_column($options, 'value');
            }
        } catch (\Exception $e) {
            // SQL查询失败或格式错误，返回空数组
            return [];
        }

        self::$dictCache[$cacheKey] = $values;
        return $values;
    }

    /**
     * 模拟获取字典数据的方法
     * @param string $dictCode
     * @return array
     */
    private function getDictValues(string $dictCode): array
    {
        $data = [
            'code' => $dictCode,
            'perms' => false,
        ];
        return $this->dictService->getDictData($data);
    }
}